package com.lingdong.onlinejudge.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lingdong.onlinejudge.common.ErrorCode;
import com.lingdong.onlinejudge.exception.BusinessException;
import com.lingdong.onlinejudge.mapper.MatchMapper;
import com.lingdong.onlinejudge.mapper.TeamMapper;
import com.lingdong.onlinejudge.mapper.UserMapper;
import com.lingdong.onlinejudge.model.dto.sign.SignDto;
import com.lingdong.onlinejudge.model.dto.sign.SignUpdateDto;
import com.lingdong.onlinejudge.model.entity.*;
import com.lingdong.onlinejudge.service.SignService;
import com.lingdong.onlinejudge.mapper.SignMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;

/**
* @author lzw
* @description 针对表【sign】的数据库操作Service实现
* @createDate 2024-02-12 20:26:24
*/
@Service
public class SignServiceImpl extends ServiceImpl<SignMapper, Sign>
    implements SignService{


    @Resource
    private SignMapper signMapper;

    @Resource
    private MatchMapper matchMapper;

    @Resource
    private UserMapper userMapper;

    @Resource
    private TeamMapper teamMapper;

    /**
     * 报名比赛
     * @param signDto 报名
     * @return 结果
     */
    @Override
    public boolean sign(SignDto signDto) {
        Long matchId = signDto.getMatchId();
        if (matchId == null){
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        QueryWrapper<Match> matchQueryWrapper = new QueryWrapper<>();
        matchQueryWrapper.eq("id", matchId);
        Match match = matchMapper.selectOne(matchQueryWrapper);
        if (match == null){
            throw new BusinessException(ErrorCode.OPERATION_ERROR);
        }
        // 判断比赛时间
        if (match.getStartTime().getTime() < System.currentTimeMillis()){
            throw new BusinessException(ErrorCode.OPERATION_ERROR,"比赛时间已过");
        }

        // 判断是否超过人数
        QueryWrapper<Sign> signCountQueryWrapper = new QueryWrapper<>();
        signCountQueryWrapper.eq("match_id", matchId);
        List<Sign> matchSignList = signMapper.selectList(signCountQueryWrapper);
        if (matchSignList.size() + 1 > match.getMatchNum()){
            throw new BusinessException(ErrorCode.OPERATION_ERROR,"报名人数或队伍数已满");
        }
        // 获取报名方式
        Integer matchType = match.getMatchType();
        Sign sign = new Sign();
        // 个人赛
        if (matchType == 0){
            Long userId = signDto.getUserId();
            if (userId == null){
                throw new BusinessException(ErrorCode.PARAMS_ERROR);
            }
            // 校验用户是否有效
            QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
            userQueryWrapper.eq("id", userId);
            User user = userMapper.selectOne(userQueryWrapper);
            if (user == null){
                throw new BusinessException(ErrorCode.NOT_FOUND_ERROR);
            }
            // 校验用户是否在同一个比赛报名
            QueryWrapper<Sign> signQueryWrapper = new QueryWrapper<>();
            signQueryWrapper.eq("match_id", matchId);
            signQueryWrapper.eq("user_id", userId);
            Sign matchSignUser = signMapper.selectOne(signQueryWrapper);
            if (matchSignUser != null){
                throw new BusinessException(ErrorCode.OPERATION_ERROR,"不能重复报名");
            }
            // 报名
            sign.setMatchId(matchId);
            sign.setUserId(userId);
        }else {
            Long teamId = signDto.getTeamId();
            if (teamId == null){
                throw new BusinessException(ErrorCode.PARAMS_ERROR);
            }
            // 校验队伍是否有效
            QueryWrapper<Team> teamQueryWrapper = new QueryWrapper<>();
            teamQueryWrapper.eq("id", teamId);
            Team team = teamMapper.selectOne(teamQueryWrapper);
            if (team == null){
                throw new BusinessException(ErrorCode.NOT_FOUND_ERROR);
            }
            // 校验队伍是否在同一个比赛报名
            QueryWrapper<Sign> signQueryWrapper = new QueryWrapper<>();
            signQueryWrapper.eq("match_id", matchId);
            signQueryWrapper.eq("team_id", teamId);
            Sign matchSignTeam = signMapper.selectOne(signQueryWrapper);
            if (matchSignTeam != null){
                throw new BusinessException(ErrorCode.OPERATION_ERROR,"不能重复报名");
            }
            // 报名
            sign.setMatchId(matchId);
            sign.setTeamId(teamId);
        }
        // 判断审核方式
        Integer isExamine = match.getIsExamine();
        if (isExamine == 1){
            // 不需要审核
            sign.setSignStatus(1);
        }
        boolean save = this.save(sign);
        if (!save){
            throw new BusinessException(ErrorCode.OPERATION_ERROR);
        }
        return true;
    }

    /**
     * 更新报名
     * @param signUpdateDto 报名
     * @return 结果
     */
    @Override
    public boolean updateSign(SignUpdateDto signUpdateDto) {
        Long id = signUpdateDto.getId();
        if (id == null){
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        Integer signStatus = signUpdateDto.getSignStatus();
        if (signStatus == null){
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        if (signStatus != 0 && signStatus != 1 && signStatus != 2){
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        QueryWrapper<Sign> signQueryWrapper = new QueryWrapper<>();
        signQueryWrapper.eq("id", id);
        Sign sign = signMapper.selectOne(signQueryWrapper);
        if (sign == null){
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR);
        }
        sign.setSignStatus(signStatus);
        boolean update = this.updateById(sign);
        if (!update){
            throw new BusinessException(ErrorCode.OPERATION_ERROR);
        }
        return true;
    }

    /**
     * 删除报名
     * @param id 报名id
     * @return 结果
     */
    @Override
    public boolean deleteSign(Long id) {
        QueryWrapper<Sign> signQueryWrapper = new QueryWrapper<>();
        signQueryWrapper.eq("id", id);
        Sign sign = signMapper.selectOne(signQueryWrapper);
        if (sign == null){
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR);
        }
        Long matchId = sign.getMatchId();
        // 判断是否在比赛开始前，否则不允许操作
        QueryWrapper<Match> matchQueryWrapper = new QueryWrapper<>();
        matchQueryWrapper.eq("id", matchId);
        Match match = matchMapper.selectOne(matchQueryWrapper);
        if (match.getStartTime().getTime() < System.currentTimeMillis()){
            throw new BusinessException(ErrorCode.OPERATION_ERROR,"比赛时间已过，无法操作");
        }
        boolean delete = this.removeById(id);
        if (!delete){
            throw new BusinessException(ErrorCode.OPERATION_ERROR);
        }
        return true;
    }

    /**
     * 根据用户id和比赛id查询是否报名
     * @param userId 用户id
     * @param matchId 比赛id
     * @return 结果
     */
    @Override
    public Sign isSign(Long userId, Long matchId) {
        QueryWrapper<Sign> signQueryWrapper = new QueryWrapper<>();
        signQueryWrapper.eq("match_id", matchId).eq("user_id", userId);
        Sign sign = signMapper.selectOne(signQueryWrapper);
        if (sign == null){
            return null;
        }
        return sign;
    }
}




